home *** CD-ROM | disk | FTP | other *** search
/ Trusted Irix /B 4.0.4 / Trusted-Irix B-4.0.1.iso / dist / eoe1.idb / usr / include / sys / fs / efs_dir.h.z / efs_dir.h
C/C++ Source or Header  |  1992-04-03  |  6KB  |  167 lines

  1. #ifndef __efs_dir__
  2. #define    __efs_dir__
  3. /*
  4.  * Long-name directory structure for the efs.
  5.  *
  6.  * $Source: /src_trees/calypso/att/usr/src/uts/mips/sys/fs/RCS/efs_dir.h,v $
  7.  * $Revision: 3.1 $
  8.  * $Date: 87/09/11 13:25:39 $
  9.  */
  10.  
  11. /*
  12.  * Directory block size corresponds to basic block (sector) size,
  13.  * for atomic writes.
  14.  */
  15. #define    EFS_DIRBSHIFT    BBSHIFT
  16. #define EFS_DIRBSIZE    BBSIZE
  17. #define    EFS_DIRBMASK    BBMASK
  18.  
  19. /*
  20.  * A dirblk is composed of 3 major components: a header, entry offsets and
  21.  * entries.  Initially, a dirblock is all zeros, except for the magic number
  22.  * and the freeoffset.  A entries are allocated, a byte is reserved at
  23.  * the beginning of the "space" array for holding the offset to the entry.
  24.  * At the end of the "space" array the actual entry is stored.  The directory
  25.  * is considered full, if a name is going to be added and (1) there is not
  26.  * enough room for the dent plus halfword alignment padding plus the the
  27.  * byte offset.
  28.  *
  29.  * The directory management procedures that return an "offset" actually
  30.  * return a magic cookie with the following format:
  31.  *    directory-block-number<23:0>|index-into-offsets<7:0>
  32.  */
  33.  
  34. /* entry structure */
  35. struct    efs_dent {
  36.     union {
  37.         ulong     l;
  38.         ushort    s[2];
  39.     } ud_inum;            /* inumber */
  40.     unchar    d_namelen;        /* length of string in d_name */
  41.     char    d_name[3];        /* name flex array */
  42. };
  43. /*
  44.  * Minimum size of a dent is the whole structure, less the 3 bytes for
  45.  * the name storage, plus one byte of a one character minimum name.
  46.  */
  47. #define    EFS_DENTSIZE    (sizeof(struct efs_dent) - 3 + 1)
  48. #define    EFS_MAXNAMELEN    ((1<<(sizeof(unsigned char)*BITSPERBYTE))-1)
  49.  
  50. /* dirblk structure */
  51. #define    EFS_DIRBLK_HEADERSIZE    4    /* size of header of dirblk */
  52. struct    efs_dirblk {
  53.     /* begin header */
  54.     ushort    magic;            /* magic number */
  55.     unchar    firstused;        /* offset to first used dent byte */
  56.     unchar    slots;            /* # of offset slots in dirblk */
  57.     /* end header */
  58.  
  59.     /* rest is space for efs_dent's */
  60.     unchar    space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE];
  61. };
  62. #define    EFS_DIRBLK_MAGIC    0xBEEF    /* moo */
  63.  
  64. /* maximum number of entries that can fit in a dirblk */
  65. #define    EFS_MAXENTS \
  66.     ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \
  67.      (EFS_DENTSIZE + sizeof(unchar)))
  68.  
  69. /*
  70.  * Given a cookie or a byte offset into a file, convert it into an offset
  71.  * to the beginning of the dirblk containing that offset/cookie.
  72.  */
  73. #define    EFS_DBOFF(cookie) \
  74.     ((cookie) & (~EFS_DIRBMASK & 0x7FFFFFFF))
  75.  
  76. /* construct a new cookie */
  77. #define    EFS_MKCOOKIE(offset, slot) \
  78.     (EFS_DBOFF(offset) | (slot))
  79.  
  80. /* given a cookie, return the slot # */
  81. #define    EFS_SLOT(cookie) \
  82.     ((cookie) & EFS_DIRBMASK)
  83.  
  84. /* given a real dirblk byte offset, compact it */
  85. #define    EFS_COMPACT(off)        ((off) >> 1)
  86.  
  87. /* given a slot, return the offset for it */
  88. #define    EFS_SLOTAT(db, slot) \
  89.     EFS_REALOFF( (db)->space[slot] )
  90.  
  91. /* given a slotoffset, return an efs_dent for it */
  92. #define    EFS_SLOTOFF_TO_DEP(db, slotoffset) \
  93.     ((struct efs_dent *) ((char *)(db) + slotoffset))
  94.  
  95. #define    EFS_SET_SLOT(db, slot, compactoffset) \
  96.     ((db)->space[slot] = (compactoffset))
  97.  
  98. /* tag for identifying free spots in the directory */
  99. #define    EFS_FREESLOT        EFS_DIRBMASK
  100.  
  101. /* given a compacted offset, turn it into a real dirblk byte offset */
  102. #define    EFS_REALOFF(coff) \
  103.     ((coff) << 1)
  104.  
  105. /*
  106.  * Given the "firstused" value, determine offset to first used byte.  A value
  107.  * of zero in "firstused" means no bytes are used, and that the offset to
  108.  * the first used byte is outside the directories space.
  109.  */
  110. #define    EFS_DIR_FREEOFF(firstused) \
  111.     (((firstused) == 0) ? EFS_DIRBSIZE : EFS_REALOFF(firstused))
  112.  
  113. /*
  114.  * Given a dirblk, compute the size of the free space.  The size of the
  115.  * is the amount of space prior to the first used byte, minus the
  116.  * amount consumed by the dirblk header and the offsets for the dents.
  117.  */
  118. #define    EFS_DIR_FREESPACE(db) \
  119.     (EFS_DIR_FREEOFF((db)->firstused) - \
  120.        (EFS_DIRBLK_HEADERSIZE + sizeof(unchar) * (db)->slots))
  121.  
  122. /*
  123.  * The efs_dentsize macro gives the minimum record length which will hold the
  124.  * directory entry pointed at by dep.  efs_dentsizebynamelen calculates the
  125.  * size of a struct efs_dent excluding the name array, and adds the name
  126.  * length.  Given a null-terminated string, efs_dentsizebyname computes the
  127.  * size of an efs_dent which has that string as its name.  The dentsize
  128.  * includes the possible padding to enforce halfword alignment.  It does
  129.  * not include the offset byte.
  130.  */
  131. #define    efs_dentsizebynamelen(namelen) \
  132.     (EFS_DENTSIZE + (namelen) - 1 + (((namelen) ^ 1) & 1) )
  133. #define    efs_dentsize(dep) \
  134.     efs_dentsizebynamelen((dep)->d_namelen)
  135. #define    efs_dentsizebyname(name) \
  136.     efs_dentsizebynamelen(strlen(name))
  137.  
  138. /*
  139.  * Because the efs_dent structure is only 6 bytes long, and some machines
  140.  * require longs to be a long boundaries, the following macros are used
  141.  * to get at the inumber.
  142.  */
  143. #if defined(mips) || defined(PM2)
  144. #define    EFS_INUM_ISZERO(dep) \
  145.     (((dep)->ud_inum.s[0] == 0) && ((dep)->ud_inum.s[1] == 0))
  146. #define    EFS_SET_INUM(dep, inum) { \
  147.     (dep)->ud_inum.s[0] = (inum) >> 16; \
  148.     (dep)->ud_inum.s[1] = (inum); \
  149. }
  150. #define    EFS_GET_INUM(dep) \
  151.     (((dep)->ud_inum.s[0] << 16) + (dep)->ud_inum.s[1])
  152. #endif
  153.  
  154. #if defined(IP2)
  155. #define    EFS_INUM_ISZERO(dep)        ((dep)->ud_inum.l == 0)
  156. #define    EFS_SET_INUM(dep, inum)        ((dep)->ud_inum.l = (inum))
  157. #define    EFS_GET_INUM(dep)        ((dep)->ud_inum.l)
  158. #endif
  159.  
  160. /*
  161.  * Minimum and maximum directory entry sizes.
  162.  */
  163. #define    EFS_MINDENTSIZE    efs_dentsizebynamelen(1)
  164. #define    EFS_MAXDENTSIZE    efs_dentsizebynamelen(EFS_MAXNAMELEN)
  165.  
  166. #endif    /* __efs_dir_ */
  167.